"use strict";

const Command = require("@azir-cli/command");
const log = require("@azir-cli/log");
const fs = require("fs");
const inquirer = require("inquirer");
const fse = require("fs-extra");
const semver = require("semver");

const TYPE_PROJECT = "project";
const TYPE_COMPONENT = "component";

class InitCommand extends Command {
  constructor(argv) {
    super(argv);
  }

  init() {
    this.projectName = this._argv[0] || "";
    this.options = this._argv[1] || {};
    log.debug("projectName", this.projectName);
    log.debug("force", this.options.force);
  }

  async exec() {
    try {
      // 1.准备阶段
      const projectInfo = await this.prepare();
      log.debug("projectInfo", projectInfo);
      if (projectInfo) {
        // 2.下载模板
        // 3.安装模板
      }
    } catch (error) {
      log.error(error.message);
    }
  }

  async prepare() {
    // 1.判断当前目录是否为空
    const localPath = process.cwd();
    const isEmptyDir = this.isEmptyDir(localPath);
    const isForce = this.options.force;
    if (!isEmptyDir) {
      let ifContinue = false;
      if (!isForce) {
        ifContinue = (
          await inquirer.prompt({
            type: "confirm",
            name: "ifContinue",
            message: "当前文件夹不为空，是否清空当前文件夹？",
          })
        ).ifContinue;
        if (!ifContinue) return false;
      }
      // 2.是否启动强制更新
      if (ifContinue || isForce) {
        const { confirmDelete } = await inquirer.prompt({
          type: "confirm",
          name: "confirmDelete",
          message: "是否确认清空当前文件夹？",
        });
        if (confirmDelete) {
          fse.emptyDirSync(localPath);
        } else {
          return false;
        }
      }
    }
    return this.getProjectInfo();
  }

  async getProjectInfo() {
    let projectInfo = {};
    const type = (
      await inquirer.prompt({
        type: "list",
        default: TYPE_PROJECT,
        message: "请选择要初始化的类型",
        name: "type",
        choices: [
          {
            name: "项目",
            value: TYPE_PROJECT,
          },
          {
            name: "组件",
            value: TYPE_COMPONENT,
          },
        ],
      })
    ).type;
    log.debug("project_type", type);
    // 3.选择创建组件还是工程
    if (type === TYPE_COMPONENT) {
      // TODO
    } else if (type === TYPE_PROJECT) {
      const info = await inquirer.prompt([
        {
          type: "input",
          name: "projectName",
          message: "请输入项目名称",
          default: "",
          filter: function (v) {
            return v;
          },
          validate: function (v) {
            const done = this.async();
            const isValid =
              /^[a-zA-Z]+([-][a-zA-Z][a-zA-Z0-9]*|[_][a-zA-Z][a-zA-Z0-9]*|[a-zA-Z0-9])*$/.test(
                v
              );
            if (!isValid) {
              done("请输入合法的项目名称");
            } else {
              done(null, true);
            }
          },
        },
        {
          type: "input",
          name: "projectVersion",
          message: "请输入项目版本号",
          default: "",
          filter: function (v) {
            if (semver.valid(v)) {
              return semver.valid(v);
            } else {
              return v;
            }
          },
          validate: function (v) {
            const done = this.async();
            const isValid = !!semver.valid(v);
            if (!isValid) {
              done("请输入合法的版本号");
            } else {
              done(null, true);
            }
          },
        },
      ]);
      projectInfo = {
        type,
        ...info,
      };
    }
    // 4.获取项目信息
    return projectInfo;
  }

  downloadTemplate() {
    // 1. 通过项目模板API获取项目模板
    // 1.1 通过egg搭建后端api
    // 1.2 通过npm项目存储模板
    // 1.3 将项目模板信息存储到 mongodb 中
    // 1.4 通过egg获取从mongodb中获取数据
  }

  isEmptyDir(dir) {
    let files = fs.readdirSync(dir);
    files = files.filter((file) => {
      return !file.startsWith(".") && !["node_modules"].includes(file);
    });
    return !files || files.length === 0;
  }
}

function init(argv) {
  return new InitCommand(argv);
}

module.exports = init;
module.exports.InitCommand = InitCommand;
